package org.balthie.demo.jdk.nio.pipe;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;

import org.balthie.demo.jdk.nio.channel.file.FileChannelExchage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Mr.X <a href=
 *         "https://blog.csdn.net/u010562966/article/details/102976363">pipe
 *         demo</a> <a href=
 *         "https://www.zhihu.com/question/39752285/answer/83207770">pipe
 *         在memcache中的应用</a>
 *
 */
public class PipeDemo {
	private static final Logger LOGGER = LoggerFactory.getLogger(PipeDemo.class);

	public static void main(String[] args) {
		try {
			Pipe pipe = Pipe.open();

			Thread t1 = new Thread(() -> {
				sink(pipe);
			});
			Thread t2 = new Thread(() -> {
				source(pipe);
			});
			t1.start();
			t2.start();
//			t1.join();
//			t2.join();

			Thread.sleep(5000);
		} catch (IOException | InterruptedException e) {
			e.printStackTrace();
		}
	}

	private static void source(Pipe pipe) {
		Pipe.SourceChannel sourceChannel = pipe.source();
		LOGGER.info("source begin sourceChannle isBlock =" +sourceChannel.isBlocking());
		
		ByteBuffer buf = ByteBuffer.allocate(256);
		try {
			int len = sourceChannel.read(buf);
			buf.flip();
			LOGGER.info(Thread.currentThread() + " sourceChannel read " + new String(buf.array(), 0, len) +"sourceChannle isBlock =" +sourceChannel.isBlocking());

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				sourceChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private static void sink(Pipe pipe) {
		LOGGER.info("sink begin");
		Pipe.SinkChannel sinkChannel = pipe.sink();
		ByteBuffer buf = ByteBuffer.allocate(256);
		buf.put("你好啊".getBytes());
		buf.flip();
		try {
			Thread.sleep(1000);
			LOGGER.info(Thread.currentThread() + " sinkChannel write 你好啊");
			sinkChannel.write(buf);
		} catch (IOException | InterruptedException e) {
			e.printStackTrace();
		} finally {
			try {
				sinkChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
